//
//  WindowManage.m
//  iDev
//
//  Created by lbxia on 2022/3/16.
//

#import "WindowManage.h"
#import <Appkit/Appkit.h>

@interface WindowManage()
@property (strong,nonatomic) NSMutableArray *applications;

@end


@implementation WindowManage

+ (instancetype)sharedManager
{
    static WindowManage* _sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[WindowManage alloc] init];
        _sharedInstance.applications = [NSMutableArray array];
        
    });
    
    return _sharedInstance;
}

- (NSImage*)test {
    
    
//    CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionIncludingWindow , kCGNullWindowID);

    //获取的只有顶部菜单栏右边的图标应用以及一些系统级应用、系统界面显示的最顶部的应用
//    CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);

    //所有打开的应用，无论是系统界面顶部右边菜单栏的，还是打开不是显示在最上层的
    CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID);

    NSArray *array = (__bridge NSArray*)windowList;
    
    for (int i = 0; i < array.count; i++) {
        
//        NSLog(@"%@",array[i]);
        NSDictionary *dic = array[i];
        
        
        int kCGWindowLayer = [dic[@"kCGWindowLayer"]intValue];
        if (kCGWindowLayer > 0) {
            
            NSLog(@"%@,%d",dic[@"kCGWindowOwnerName"],kCGWindowLayer);
            
            /*
            经测试24表示打开且有窗口的app，其他如cleanmymac应用已经启动且在系统窗口顶部右边显示的小图标，qq会有2个，一个图标，一个窗口
            但是所有
             kCGWindowBounds =     {
                 Height = 24;
                 Width = 2560;
                 X = 0;
                 Y = 0;
             };
             Height都是24,获取的应用窗口缩略图也不正确
             */
            if (kCGWindowLayer == 24) {
                
                NSLog(@"%@",dic);
            }

//            NSLog(@"%@",dic);
            
//            NSLog(@"\r\n\r\n");
            
//            NSWindow *window = NSApp.window(withWindowNumber: [dic[@"kCGWindowNumber"]intValue] )
            
            //NSWindow截图，获取当缩略图 ？ 不可能获取到NSApplication.sharedApplication 是当前应用的。。。
            NSWindow *window = [NSApplication.sharedApplication windowWithWindowNumber:[dic[@"kCGWindowNumber"]intValue]];
            
            if (window) {
                //一个都获取不到
                NSLog(@" has window");
            }
            
            if ([dic[@"kCGWindowNumber"]intValue] == 106) {
                
                //获取到的是系统顶部菜单栏的app图标
                return [self captureScrenImage:dic];
            }
            
            
            /*
             {
                kCGWindowAlpha = 1;
                kCGWindowBounds =     {
                    Height = 46;
                    Width = 168;
                    X = 2048;
                    Y = 26;
                };
                kCGWindowIsOnscreen = 1;
                kCGWindowLayer = 25;
                kCGWindowMemoryUsage = 1232;
                kCGWindowNumber = 392;
                kCGWindowOwnerName = "QQ.app";
                kCGWindowOwnerPID = 382;
                kCGWindowSharingState = 0;
                kCGWindowStoreType = 1;
            }
            */

        }
    }
    
    NSLog(@"count:%d",array.count);
    return  nil;
}

- (NSImage*)captureScrenImage:(NSDictionary *)windowDict {
    
    
//    return [self imageDestop];
    
    CGRect windowRect;
    CGRectMakeWithDictionaryRepresentation((__bridge CFDictionaryRef)(windowDict[(id)kCGWindowBounds]), &windowRect);
    
    CGWindowID windowID = (CGWindowID)[windowDict[(id)kCGWindowNumber] unsignedLongLongValue];
//    CGImageRef cgImage = CGWindowListCreateImage(windowRect,  kCGWindowListOptionOnScreenOnly, windowID, kCGWindowImageBoundsIgnoreFraming);
//    CGImageRef cgImage = CGWindowListCreateImage(CGRectInfinite,  kCGWindowListOptionIncludingWindow, windowID, kCGWindowImageDefault);
    
    CGImageRef cgImage =
        CGWindowListCreateImage(CGRectNull, kCGWindowListOptionIncludingWindow,
                                windowID, kCGWindowImageDefault);

    NSImage *image = [self imageFromCGImageRef:cgImage];
    
    return  image;
}

- (NSImage*)imageDestop {
    
    CGImageRef cgImage = CGWindowListCreateImage(CGRectInfinite,  kCGWindowListOptionOnScreenOnly, 0, kCGWindowImageDefault);

    NSImage *image = [self imageFromCGImageRef:cgImage];
    
    return  image;

}

- (NSImage *)imageFromCGImageRef:(CGImageRef)image {
    NSRect imageRect = NSMakeRect(0.0, 0.0, 0.0, 0.0);
    
    // Get the image dimensions.
    imageRect.size.height = CGImageGetHeight(image);
    imageRect.size.width = CGImageGetWidth(image);
    
    // Create a new image to receive the Quartz image data.
    NSImage *newImage = [[NSImage alloc] initWithCGImage:image size:imageRect.size];
    return newImage;
}

- (NSRect)cgWindowRectToScreenRect:(CGRect)windowRect {
    NSRect mainRect = [NSScreen mainScreen].frame;
    for (NSScreen *screen in [NSScreen screens]) {
        if ((int) screen.frame.origin.x == 0 && (int) screen.frame.origin.y == 0) {
            mainRect = screen.frame;
        }
    }
    
    NSRect rect = NSMakeRect(windowRect.origin.x, mainRect.size.height - windowRect.size.height - windowRect.origin.y, windowRect.size.width, windowRect.size.height);
    return rect;
}

#pragma mark- Capture Application Views
- (void)getWindowsInfoOnScreens {
    NSArray<NSRunningApplication *> *openWindows = [[NSWorkspace sharedWorkspace] runningApplications];
    
    NSMutableArray *details = [NSMutableArray arrayWithCapacity:openWindows.count];
    [openWindows enumerateObjectsUsingBlock:^(NSRunningApplication * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        NSDictionary *detail = @{@"localizedName": obj.localizedName,
                                 @"processIdentifier": @(obj.processIdentifier),
                                 };
        [details addObject:detail];
    }];
    
    NSLog(@"应用信息个数:%ld", details.count);
    NSArray *arrs = (__bridge NSArray*) CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
    [arrs enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull windowDict, NSUInteger idx, BOOL * _Nonnull stop) {
        int layer = 0;
        CFNumberRef numberRef = (__bridge CFNumberRef) windowDict[(id) kCGWindowLayer];
        CFNumberGetValue(numberRef, kCFNumberSInt32Type, &layer);
        
        if (layer >=0 ) {
            [self.applications addObject:windowDict];
        }
    }];
    
    NSLog(@"有效的窗口个数:%ld, 详情：%@", self.applications.count, self.applications);
}

- (NSString *)jsonStringFromObject:(id)object {
    if (!object) {
        return @"";
    }
    
    NSError *error = nil;
    NSData *objectData = [NSJSONSerialization dataWithJSONObject:object options:0 error:&error];
    if (error) {
        NSLog(@"对象转Json字符串失败:%@", error);
        return @"";
    }
    
    return [[NSString alloc] initWithData:objectData encoding:NSUTF8StringEncoding];
}

@end
